<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Channel Detail</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
    <style>
        body, html { background: #18181a !important; color: #fff; overflow-x: hidden; }
        .channel-bg {
            position: relative;
            width: 100vw;
            height: 100vh;
            background: #222;
            overflow: hidden;
        }
        .channel-bg-img {
            width: 100vw;
            height: 100vh;
            object-fit: cover;
            filter: brightness(0.55);
        }
        .channel-bg-overlay {
            position: absolute; left: 0; top: 0; width: 100%; height: 100%;
            background: linear-gradient(90deg, #18181a 0%, #18181aa0 40%, #18181a00 100%);
        }
        .channel-main-info {
            position: absolute; left: 0; top: 0; width: 100%; height: 100%;
            display: flex; flex-direction: column; justify-content: center; padding-left: 80px; z-index: 2;
        }
        .channel-title {
            font-size: 2.6em; font-weight: bold; letter-spacing: 0.01em; margin-bottom: 10px;
            max-width: 65vw;
            word-break: break-word;
            margin-right: 32px;
        }
        .channel-meta { color: #eee; font-size: 1.1em; margin-bottom: 10px; }
        .channel-desc {
            color: #ccc; font-size: 1.08em; max-width: 700px; margin-bottom: 18px;
            display: -webkit-box;
            -webkit-line-clamp: 4;
            -webkit-box-orient: vertical;
            overflow: hidden;
            position: relative;
            transition: max-height 0.2s;
        }
        .channel-desc.expanded {
            -webkit-line-clamp: unset;
            max-height: none;
            overflow: visible;
        }
        #descMoreBtnWrap {
            margin-top: 2px;
            margin-bottom: 10px;
            display: none;
        }
        #descMoreBtn {
            background: none;
            border: none;
            color: #4ea3ff;
            font-size: 1em;
            cursor: pointer;
            margin-top: 4px;
            margin-left: 0;
            padding: 0;
            display: none;
        }
        .channel-platforms { display: flex; gap: 12px; margin-bottom: 18px; }
        .channel-platform-btn { background: #222; border: none; border-radius: 8px; padding: 8px 16px; color: #fff; font-size: 1.1em; display: flex; align-items: center; gap: 8px; transition: background 0.2s; }
        .channel-platform-btn img { width: 32px; height: 32px; border-radius: 6px; }
        .channel-platform-btn:hover { background: #444; }
        .channel-section { margin: 0 auto; max-width: 1400px; padding: 0 40px; }
        .channel-actions { display: flex; gap: 16px; margin-bottom: 8px; }
        .channel-action-btn { background: #222; border: none; border-radius: 12px; padding: 10px 16px; color: #fff; font-size: 1.2em; display: flex; align-items: center; gap: 8px; transition: background 0.2s; }
        .channel-action-btn img { width: 28px; height: 28px; border-radius: 6px; }
        .channel-action-btn:hover { background: #444; }
        .channel-action-label { font-size: 0.98em; color: #ccc; margin-top: 2px; }
        .programs-title { color: #fff; font-size: 1.1em; font-weight: bold; margin: 32px 0 12px 0; }
        .programs-list {
            display: flex; gap: 18px; overflow-x: auto; padding-bottom: 8px; margin-bottom: 18px;
            scrollbar-width: thin; scrollbar-color: #444 #222;
        }
        .programs-list::-webkit-scrollbar {
            height: 8px; background: #222; border-radius: 6px;
        }
        .programs-list::-webkit-scrollbar-thumb {
            background: #444; border-radius: 6px;
        }
        .programs-list::-webkit-scrollbar-thumb:hover {
            background: #666;
        }
        .program-item { width: 400px; min-width: 400px; background: #222; border-radius: 12px; overflow: hidden; margin-bottom: 8px; cursor: pointer; transition: box-shadow 0.18s, transform 0.18s; border: 2px solid transparent; }
        .program-item.selected { border: 2px solid #fff; }
        .program-item img { width: 100%; height: 225px; object-fit: cover; }
        .program-item .program-caption { color: #fff; font-size: 1em; font-weight: 500; padding: 8px 12px 0 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .program-item .program-meta { color: #bbb; font-size: 0.97em; padding: 0 12px 8px 12px; }
        .program-item .program-duration { color: #aaa; font-size: 0.92em; padding: 0 12px 8px 12px; }
        .program-meta-detail { color: #bbb; font-size: 1em; margin-bottom: 18px; }
        .channels-title { color: #fff; font-size: 1.1em; font-weight: bold; margin: 32px 0 12px 0; }
        .channels-list {
            display: flex; gap: 18px; overflow-x: auto; padding-bottom: 8px; margin-bottom: 18px;
            scrollbar-width: thin; scrollbar-color: #444 #222;
        }
        .channels-list::-webkit-scrollbar {
            height: 8px; background: #222; border-radius: 6px;
        }
        .channels-list::-webkit-scrollbar-thumb {
            background: #444; border-radius: 6px;
        }
        .channels-list::-webkit-scrollbar-thumb:hover {
            background: #666;
        }
        .channels-item { width: 400px; min-width: 400px; background: #222; border-radius: 12px; overflow: hidden; margin-bottom: 8px; cursor: pointer; transition: box-shadow 0.18s, transform 0.18s; }
        .channels-item img { width: 100%; height: 225px; object-fit: cover; }
        .channels-item .channels-caption { color: #fff; font-size: 1em; font-weight: 500; padding: 8px 12px 0 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        @media (max-width: 900px) {
            .channel-main-info { padding-left: 24px; }
            .channel-section { padding: 0 10px; }
        }
    </style>
</head>
<body>
    <div class="channel-bg">
        <img class="channel-bg-img" id="channelBgImg" src="" alt="">
        <div class="channel-bg-overlay"></div>
        <div class="channel-main-info">
            <div class="channel-title" id="channelTitle">Channel Title</div>
            <div class="channel-meta" id="channelMeta"></div>
            <div class="channel-desc" id="channelDesc"></div>
            <div id="descMoreBtnWrap"><span id="descMoreBtn" style="color:#4ea3ff;cursor:pointer;">more</span></div>
            <div class="channel-actions" id="channelActions"></div>
            <div class="channel-platforms" id="channelPlatforms"></div>
        </div>
    </div>
    <div class="channel-section">
        <div class="programs-title">Today's Program</div>
        <div class="programs-list" id="programsList"></div>
        <div class="program-meta-detail" id="programMetaDetail"></div>
        <div class="channels-title">More Channels Like This</div>
        <div class="channels-list" id="channelsList"></div>
    </div>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
    // ========== 工具 ==========
    function getQueryParam(name) {
        const url = window.location.search;
        const params = new URLSearchParams(url);
        return params.get(name);
    }
    function buildApiUrl(token, value) {
        return `https://saas.zeasn.tv/sp/api/device/v1/column/resourceDetail?token=${encodeURIComponent(token)}&resourceType=12&value=${encodeURIComponent(value)}&needPoster=true&posterWidth=1280&needAward=true`;
    }
    // ========== 数据加载 ==========
    async function loadChannelDetail() {
        const token = getQueryParam('token');
        const value = getQueryParam('value');
        if (!token || !value) {
            $('#channelTitle').text('参数缺失，无法加载频道详情');
            return;
        }
        const API_URL = buildApiUrl(token, value);
        let currentChannelId = '';
        try {
            const res = await fetch(API_URL);
            const data = await res.json();
            if (!data.data) {
                $('#channelTitle').text('未获取到频道详情');
                return;
            }
            const d = data.data;
            // 获取当前频道id
            try {
                const vObj = typeof value === 'string' ? JSON.parse(decodeURIComponent(value)) : value;
                // 确保 id 保持字符串格式，避免 Number 类型转换导致精度丢失
                currentChannelId = String(vObj.id);
            } catch(e) { currentChannelId = String(d.id); }
            // 顶部大图
            const poster = (d.posters && d.posters[0] && d.posters[0].url) || (d.covers && d.covers[0] && d.covers[0].url) || '';
            $('#channelBgImg').attr('src', poster);
            // 标题
            $('#channelTitle').text(d.name || '');
            // meta
            let metaArr = [];
            if (Array.isArray(d.categories) && d.categories.length > 0) metaArr.push(d.categories.map(c=>c.name).join(' • '));
            if (d.ratingTag) metaArr.push(`<span class='badge bg-secondary'>${d.ratingTag}</span>`);
            $('#channelMeta').html(metaArr.join(' '));
            // 简介
            let descText = d.description || '';
            function handleDescCollapse() {
                const $desc = $('#channelDesc');
                const $btnWrap = $('#descMoreBtnWrap');
                const $btn = $('#descMoreBtn');
                $desc.data('full', descText);
                function update(expanded) {
                    $desc.toggleClass('expanded', expanded);
                    $btn.text(expanded ? 'less' : 'more');
                }
                // 先展开测真实行数
                $desc.text(descText);
                $desc.addClass('expanded');
                $btnWrap.hide();
                $btn.hide();
                setTimeout(() => {
                    // 获取真实高度和单行高度
                    const realHeight = $desc[0].scrollHeight;
                    $desc.removeClass('expanded');
                    // 现在是省略状态，测省略高度
                    const clampHeight = $desc[0].clientHeight;
                    // 重新展开测单行高度
                    $desc.addClass('expanded');
                    $desc[0].style.webkitLineClamp = 'unset';
                    const lineHeight = parseFloat(window.getComputedStyle($desc[0]).lineHeight);
                    const lines = Math.round(realHeight / lineHeight);
                    $desc.removeClass('expanded');
                    $desc[0].style.webkitLineClamp = '';
                    update(false);
                    if (lines > 4) {
                        $btnWrap.show();
                        $btn.show();
                        $btn.off('click').on('click', function() {
                            update(!$desc.hasClass('expanded'));
                        });
                    } else {
                        $btnWrap.hide();
                        $btn.hide();
                    }
                }, 100);
            }
            handleDescCollapse();
            // 平台按钮
            $('#channelPlatforms').empty();
            if (Array.isArray(d.deeplinks) && d.deeplinks.length > 0) {
                d.deeplinks.forEach(link => {
                    const icon = link.sourceIcon || '';
                    const name = link.sourceName || '';
                    $('#channelPlatforms').append(`<button class='channel-platform-btn'><img src='${icon}'><span>${name}</span></button>`);
                });
            }
            // 频道操作按钮（如点赞、评论、分享等）
            $('#channelActions').empty();
            // 今日节目
            async function loadTodaysPrograms(token, value) {
                $('#programsList').empty().append('<div style="color:#aaa;padding:32px 0;">Loading...</div>');
                if (!token || !value) return;
                
                const url = `https://saas.zeasn.tv/sp/api/device/v1/program?token=${encodeURIComponent(token)}&userToken=fTsdbutaIUU1gNq-milco4ujsnY1x9i-Yz_9NWOwZlg&startIndex=0&iconShape=HORIZONTAL&value=${encodeURIComponent(value)}&size=30`;
                
                try {
                    const res = await fetch(url);
                    const data = await res.json();
                    if (!data.data || !Array.isArray(data.data) || data.data.length === 0) {
                        $('#programsList').html('<div style="color:#aaa;padding:32px 0;">暂无节目</div>');
                        return;
                    }
                    
                    $('#programsList').empty();
                    data.data.forEach((item, idx) => {
                        const img = item.poster || item.icon || '';
                        const title = item.name || '';
                        const time = item.startTime && item.endTime ? `${item.startTime} - ${item.endTime}` : '';
                        const selected = idx === 0 ? 'selected' : '';
                        $('#programsList').append(`
                            <div class='program-item ${selected}'>
                                <img src='${img}' alt='${title}'>
                                <div class='program-caption'>${title}</div>
                                <div class='program-meta'>${time}</div>
                            </div>
                        `);
                    });
                    
                    // 选中第一个，展示下方 meta
                    const first = data.data[0];
                    if (first) {
                        $('#programMetaDetail').html(`<div style='font-size:1.1em;color:#fff;'>${first.name || ''}</div><div style='color:#bbb;font-size:1em;'>${first.duration || ''}</div>`);
                    }
                    
                    // 点击切换选中
                    $('.program-item').on('click', function(){
                        $('.program-item').removeClass('selected');
                        $(this).addClass('selected');
                        const idx = $(this).index();
                        const item = data.data[idx];
                        $('#programMetaDetail').html(`<div style='font-size:1.1em;color:#fff;'>${item.name || ''}</div><div style='color:#bbb;font-size:1em;'>${item.duration || ''}</div>`);
                    });
                } catch (e) {
                    $('#programsList').html('<div style="color:#aaa;padding:32px 0;">加载失败</div>');
                }
            }
            
            // 调用今日节目接口
            loadTodaysPrograms(token, value);
            // 更多频道推荐
            async function loadMoreChannelsLikeThis(token, channelValue) {
                $('#channelsList').empty().append('<div style="color:#aaa;padding:32px 0;">Loading...</div>');
                if (!token || !channelValue) return;
                let videoId = '';
                try {
                    // 智能解码：尝试多次解码直到无法继续
                    let decodedValue = channelValue;
                    let decodeCount = 0;
                    const maxDecodes = 3;
                    while (decodeCount < maxDecodes) {
                        try {
                            const testDecode = decodeURIComponent(decodedValue);
                            if (testDecode === decodedValue) {
                                break;
                            }
                            decodedValue = testDecode;
                            decodeCount++;
                        } catch(e) {
                            break;
                        }
                    }
                    // 方法1: 尝试直接解析 JSON
                    try {
                        const parsed = JSON.parse(decodedValue);
                        if (parsed && parsed.id !== undefined) {
                            videoId = String(parsed.id);
                        }
                    } catch(jsonError) {
                        // 方法2: 尝试正则表达式提取
                        let idMatch = decodedValue.match(/"id":\s*(\d+)/);
                        if (!idMatch) {
                            idMatch = decodedValue.match(/"id"\s*:\s*(\d+)/);
                        }
                        if (!idMatch) {
                            idMatch = decodedValue.match(/id["\s]*:["\s]*(\d+)/);
                        }
                        if (!idMatch) {
                            idMatch = decodedValue.match(/id["\s]*:["\s]*[\"]*(\d+)[\"]*/);
                        }
                        if (!idMatch) {
                            idMatch = decodedValue.match(/id["\s]*:["\s]*(\d+)/i);
                        }
                        if (!idMatch) {
                            idMatch = decodedValue.match(/"id":\s*"?(\d+)"?/);
                        }
                        if (idMatch) {
                            videoId = idMatch[1];
                        }
                    }
                    if (!videoId) {
                        console.error('无法从 channelValue 中提取 id');
                        // 备用方案：尝试从URL中直接提取数字作为ID
                        const urlMatch = window.location.search.match(/[?&]value=([^&]+)/);
                        if (urlMatch) {
                            const urlValue = urlMatch[1];
                            const numberMatch = urlValue.match(/(\d+)/);
                            if (numberMatch) {
                                videoId = numberMatch[1];
                            }
                        }
                        if (!videoId) {
                            $('#channelsList').html('<div style="color:#ff6666;padding:32px 0;">无法提取频道ID</div>');
                            return;
                        }
                    }
                } catch(e) {
                    console.error('解析 channelValue 失败:', e);
                    $('#channelsList').html('<div style="color:#ff6666;padding:32px 0;">解析频道参数失败</div>');
                    return;
                }
                const url = `https://saas.zeasn.tv/sp/api/device/v1/video/recommend?token=${encodeURIComponent(token)}&videoType=REC_CHANNEL&size=10&needPoster=true&imgStyle=1&videoId=${encodeURIComponent(videoId)}`;
                try {
                    const res = await fetch(url);
                    const data = await res.json();
                    if (!data.data || !Array.isArray(data.data) || data.data.length === 0) {
                        $('#channelsList').html('<div style="color:#aaa;padding:32px 0;">暂无推荐</div>');
                        return;
                    }
                    $('#channelsList').empty();
                    data.data.forEach(item => {
                        const img = item.poster || item.icon || '';
                        const title = item.name || '';
                        let categoriesStr = '';
                        if (item.moreInfo && Array.isArray(item.moreInfo.categories) && item.moreInfo.categories.length > 0) {
                            categoriesStr = `<div style='color:#ffb84d;font-size:0.97em;padding:0 12px 2px 12px;'>${item.moreInfo.categories.map(c => c.name).join(' / ')}</div>`;
                        } else if (Array.isArray(item.categories) && item.categories.length > 0) {
                            categoriesStr = `<div style='color:#ffb84d;font-size:0.97em;padding:0 12px 2px 12px;'>${item.categories.join(' / ')}</div>`;
                        }
                        // value展示
                        const valueStr = item.value ? `<div style='color:#bbb;font-size:0.92em;word-break:break-all;padding:0 12px 2px 12px;'>${item.value}</div>` : '';
                        const $item = $(
                            `<div class='channels-item' style='cursor:pointer;'>
                                <img src='${img}' alt='${title}'>
                                <div class='channels-caption'>${title}</div>
                                ${categoriesStr}
                                ${valueStr}
                            </div>`
                        );
                        // 跳转到频道详情页，value参数处理方式与 video-detail.html 完全一致
                        $item.on('click', function() {
                            let valueStrParam = item.value ? (typeof item.value === 'string' ? item.value : JSON.stringify(item.value)) : '';
                            window.open(`channel-detail.html?token=${encodeURIComponent(token)}&value=${encodeURIComponent(valueStrParam)}`, '_blank');
                        });
                        $('#channelsList').append($item);
                    });
                } catch (e) {
                    $('#channelsList').html('<div style="color:#aaa;padding:32px 0;">加载失败</div>');
                }
            }
            // 调用
            loadMoreChannelsLikeThis(token, value);
        } catch (e) {
            $('#channelTitle').text('加载失败');
        }
    }
    $(function(){
        loadChannelDetail();
        // 鼠标滚轮横向滚动
        $('.programs-list, .channels-list').on('wheel', function(e) {
            if (e.originalEvent.deltaY === 0) return;
            this.scrollLeft += e.originalEvent.deltaY;
            e.preventDefault();
        });
    });
    </script>
</body>
</html> 